package cn.szzsi;

/**
 * Created by weimin28 on 2017/2/20.
 */

import cn.szzsi.business.apiservice.ConfigService;
import cn.szzsi.business.controller.AdminRoutes;
import cn.szzsi.business.controller.WebRoutes;
import cn.szzsi.common.util.CommonUtil;
import cn.szzsi.common.util.SerialNumberUtil;
import cn.szzsi.core.CommonRoutes;
import cn.szzsi.core.CoreConfig;
import cn.szzsi.core.MyProp;
import cn.szzsi.core.file.Files;
import cn.szzsi.core.interceptor.ExceptionInterceptor;
import cn.szzsi.core.plugin.dubbo.DubboPlugin;
import cn.szzsi.model.PlateformConfig;
import cn.szzsi.model._MappingKit;
import cn.szzsi.model.mall._MallMappingKit;
import cn.szzsi.platform.controller.AdminPlatformRoutes;
import cn.szzsi.platform.controller.WebPlatformRoutes;
import cn.szzsi.programmer.controller.ProgrammerRoutes;
import cn.szzsi.aci.service.ConfigInterface;
import cn.szzsi.aci.service.MemberInterface;
import cn.szzsi.aci.service.StoreInterface;
import cn.szzsi.aci.service.ThirdApiInterface;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.config.*;
import com.jfinal.core.JFinal;
import com.jfinal.json.MixedJsonFactory;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.cron4j.Cron4jPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.plugin.redis.Redis;
import com.jfinal.plugin.redis.RedisPlugin;
import com.jfinal.template.Engine;
//import org.beetl.ext.jfinal.BeetlRenderFactory;
import org.beetl.ext.jfinal3.JFinal3BeetlRenderFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * Config
 */
public class AConfig extends JFinalConfig {
    private static final Logger LOG = LoggerFactory.getLogger(AConfig.class);

    private  final static Prop pr= CoreConfig.pr;
    public static MyProp p = CoreConfig.p;

    //private static Prop p = loadConfig();
    private WallFilter wallFilter;
    public static ExecutorService fixedThreadPool;


    /**
     * 启动入口，运行此 main 方法可以启动项目，此main方法可以放置在任意的Class类定义中，不一定要放于此
     *
     * 使用本方法启动过第一次以后，会在开发工具的 debug、run configuration 中自动生成
     * 一条启动配置项，可对该自动生成的配置再继续添加更多的配置项，例如 VM argument 可配置为：
     * -XX:PermSize=64M -XX:MaxPermSize=256M
     * 上述 VM 配置可以缓解热加载功能出现的异常
     */
    public static void main(String[] args) {
        /**
         * 特别注意：Eclipse 之下建议的启动方式
         */
//		JFinal.start("src/main/webapp", 8080, "/", 5);

        /**
         * 特别注意：IDEA 之下建议的启动方式，仅比 eclipse 之下少了最后一个参数
         */
        JFinal.start("src/main/webapp", 8080, "/");
    }

    /*private static Prop loadConfig() {
        try {
            // 优先加载生产环境配置文件
            return AConfig.p;
        } catch (Exception e) {
            // 找不到生产环境配置文件，再去找开发环境配置文件
            return PropKit.use("config_dev.properties");
        }
    }*/



    public void configConstant(Constants me) {
        me.setErrorView(401, "/html/401.html");
        me.setErrorView(403, "/html/403.html");
        me.setError404View("/html/404.html");
        me.setError500View("/html/500.html");

        // beetl jfinal2集成
//        me.setMainRenderFactory(new BeetlRenderFactory());
        //beetl jfinal3集成
		JFinal3BeetlRenderFactory rf = new JFinal3BeetlRenderFactory();
		rf.config();
		me.setRenderFactory(rf);

        // 设定为开发者模式
        boolean bo=false;
        if(0==pr.getInt("devMode")){
            bo=true;
        }
        me.setDevMode(bo);
        me.setJsonFactory(MixedJsonFactory.me());
    }

    /**
     * 路由拆分到 FrontRutes 与 AdminPlatformRoutes 之中配置的好处：
     * 1：可分别配置不同的 baseViewPath 与 Interceptor
     * 2：避免多人协同开发时，频繁修改此文件带来的版本冲突
     * 3：避免本文件中内容过多，拆分后可读性增强
     * 4：便于分模块管理路由
     */
    public void configRoute(Routes me) {
        me.add(new AdminRoutes());//商户后台
        me.add(new WebRoutes());//商户前台
        me.add(new AdminPlatformRoutes());//超管后台
        me.add(new WebPlatformRoutes());//超管前台
        me.add(new ProgrammerRoutes());//程序员用
        me.add(new CommonRoutes());//公用
    }
    /**
     * 抽取成独立的方法，例于 _Generator 中重用该方法，减少代码冗余
     */
    public static DruidPlugin getDruidPlugin() {
        return new DruidPlugin(p.get("zshopJdbcUrl"), p.get("user"), p.get("password").trim());
    }
    /**
     * 配置模板引擎，通常情况只需配置共享的模板函数
     */
    public void configEngine(Engine me) {

    }

    public void configPlugin(Plugins me) {
        DruidPlugin druidPlugin = getDruidPlugin();
        wallFilter = new WallFilter();              // 加强数据库安全
        wallFilter.setDbType("mysql");
        druidPlugin.addFilter(wallFilter);
        druidPlugin.addFilter(new StatFilter());    // 添加 StatFilter 才会有统计数据
        me.add(druidPlugin);

        ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
        arp.setTransactionLevel(Connection.TRANSACTION_READ_COMMITTED);
        _MappingKit.mapping(arp);
        me.add(arp);

        if(0==pr.getInt("devMode")){
            arp.setShowSql(true);
        }


        me.add(new EhCachePlugin());

        //----文件服务器数据源配置start
        DruidPlugin dsMysql = new DruidPlugin(p.get("jdbcFile"), p.get("userFile"), p.get("passwordFile").trim());
        me.add(dsMysql);
        ActiveRecordPlugin arpMysql = new ActiveRecordPlugin(CommonUtil.ZSHOP_FILE, dsMysql);
        me.add(arpMysql);
        arpMysql.addMapping("sys_files", Files.class);
        //----文件服务器数据源配置end

        //----mall数据源配置start
        DruidPlugin mallMysql = new DruidPlugin(p.get("mallJdbcUrl"), p.get("user"), p.get("password").trim());
        me.add(mallMysql);
        ActiveRecordPlugin mallRecord = new ActiveRecordPlugin(CommonUtil.ZSHOP_MALL, mallMysql);
        me.add(mallRecord);
        _MallMappingKit.mapping(mallRecord);
        //----mall数据源配置end


        //任务调度
        me.add(new Cron4jPlugin(PropKit.use("task.properties")));

        //缓存服务器
        //信息缓存
        RedisPlugin redisPlugin = new RedisPlugin("zshop", AConfig.p.get("redis.host"), AConfig.p.get("redis.password"));
        redisPlugin.getJedisPoolConfig().setMaxTotal(100);
        me.add(redisPlugin);

        //dubbo插件
        DubboPlugin dubboPlugin = new DubboPlugin();
        dubboPlugin.setApplication("dubbo_zshop");
        RegistryConfig registry = new RegistryConfig();
        registry.setProtocol(p.get("dubbo.registry.protocol"));
        registry.setAddress(p.get("dubbo.registry.address"));
        dubboPlugin.setRegistry(registry);
        dubboPlugin.export(ConfigInterface.class,new ConfigService());//商户配置相关
        //dubboPlugin.export(MemberInterface.class, new MemberService());//会员信息操作相关
        //dubboPlugin.export(StoreInterface.class,new StoreService());//门店信息相关

        //dubboPlugin.export(ThirdApiInterface.class,new ThirdApiService());////第三方调用相关
        me.add(dubboPlugin);
        //dubbo插件

    }

    public void configInterceptor(Interceptors me) {
        ExceptionInterceptor exceptionInterceptor=new ExceptionInterceptor();
        me.add(exceptionInterceptor);
    }

    public void configHandler(Handlers me) {

    }


    public void beforeJFinalStop(){
        fixedThreadPool.shutdown();
    }

    /**
     * 本方法会在 jfinal 启动过程完成之后被回调，详见 jfinal 手册
     */
    public void afterJFinalStart() {
        SerialNumberUtil.lastSnNumberInit();//初始化交易编号
        PlateformConfig plateformConfig=PlateformConfig.dao.findById("1");
        JSONObject jsonObject= JSON.parseObject(JsonKit.toJson(plateformConfig));
        Redis.use("zshop").set("plateformConfig",jsonObject);

        fixedThreadPool= Executors.newFixedThreadPool(50);
    }
}







